package org.foj.presenter {
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.UIComponent;
import mx.managers.CursorManager;
import mx.managers.PopUpManager;
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

import org.foj.dto.Comment;
import org.foj.dto.Issue;
import org.foj.dto.User;
import org.foj.event.EventDispatcherFactory;
import org.foj.event.UIEvent;
import org.foj.event.UserEvent;
import org.foj.model.CommentModel;
import org.foj.view.CommentsView;
import org.foj.view.EditCommentForm;

public class CommentsListPresenter {

    private var _currentUser:User;
    private var _selectedIssue:Issue;
    private var _selectedComment:Comment;
    private var _commentModel:CommentModel;
    private var _view:CommentsView;
    private var _pop1:EditCommentForm;

    public function CommentsListPresenter(view:CommentsView = null) {

        this._commentModel = new CommentModel();

        this._view = view;

        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.SELECTED_ISSUE_CHANGED,
                changeSelectedIssue);

        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.DELETE_COMMENT_BUTTON_PRESSED,
                removeComment);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.SELECTED_COMMENT_CHANGED,
                changeSelectedComment);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.COMMENTS_UPDATED,
                refreshComments);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.ADD_NEW_COMMENT_BUTTON_PRESSED,
                addNewComment);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.EDIT_COMMENT_BUTTON_PRESSED,
                editComment);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.SAVE_COMMENT_BUTTON_PRESSED,
                saveComment);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.CANCEL_EDIT_COMMENT_BUTTON_PRESSED,
                cancelEdit);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.COMMENTS_UPDATED,
                refreshComments);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UserEvent.CURRENT_USER_UPDATED,
                currentUserChanged);
    }

     private function currentUserChanged(event:UserEvent):void {
        _currentUser = event.data;
      }

    private function get selectedIssue():Issue {
        return this._selectedIssue;
    }

    private function set selectedIssue(issue:Issue):void {
        this._selectedIssue = issue;
        _view.addCommentButton.enabled = (issue.id > 0);
    }

    private function get selectedComment():Comment {
        return this._selectedComment;
    }

    private function set selectedComment(comment:Comment):void {
        this._selectedComment = comment;
        _view.editCommentButton.enabled = (comment != null);
        _view.deleteCommentButton.enabled = (comment != null);
    }

    private function changeSelectedIssue(event:UIEvent):void {
        selectedIssue = event.data;
        selectedComment = null;
        refreshComments();
    }

    private function changeSelectedComment(event:UIEvent):void {
        selectedComment = event.data;
    }

    private function removeComment(event:* = null):void {
        CursorManager.setBusyCursor();
        _commentModel.removeComment(selectedComment.id,
                new AsyncResponder(removeCommentResult, handleError));
    }

    private function refreshComments(event:* = null):void {
        CursorManager.setBusyCursor();
        _commentModel.getCommentsForIssueId(selectedIssue.id,
                new AsyncResponder(loadCommentsResult, handleError));
    }

    private function removeCommentResult(event:ResultEvent,
                                         token:AsyncToken = null):void {
        CursorManager.removeBusyCursor();
        refreshComments();
    }

    private function loadCommentsResult(event:ResultEvent,
                                        token:AsyncToken = null):void {
        CursorManager.removeBusyCursor();
        var comments:ArrayCollection = new ArrayCollection();
        for each (var result:* in event.result) {
            comments.addItem(new Comment(result));
        }
        _view.commentsList.dataProvider = comments;
        _view.commentsList.selectedIndex = -1;
        selectedComment = null;
    }

    private function handleError(event:FaultEvent,
                                 token:AsyncToken = null):void {
        CursorManager.removeBusyCursor();
        Alert.show(event.fault.faultString);
    }
    private function addNewComment(event:* = null):void {
        selectedComment = new Comment();
        selectedComment.issue = selectedIssue;
        _pop1 = PopUpManager.createPopUp((_view as UIComponent).root,
                EditCommentForm, true) as EditCommentForm;
        _pop1.author.text = _currentUser.fullName;
        PopUpManager.centerPopUp(_pop1 as UIComponent);
    }
    private function editComment(event:* = null):void {
        _pop1 = PopUpManager.createPopUp((_view as UIComponent).root,
                EditCommentForm, true) as EditCommentForm;
        PopUpManager.centerPopUp(_pop1 as UIComponent);
        _pop1.author.text = selectedComment.author;
        _pop1.commentDate.selectedDate = selectedComment.createdDate;
        _pop1.commentText.text = selectedComment.commentText;
    }
    private function saveComment(event:* = null):void {
        CursorManager.setBusyCursor();
        selectedComment.author = _pop1.author.text;
        selectedComment.createdDate = _pop1.commentDate.selectedDate;
        selectedComment.commentText = _pop1.commentText.text;
        _commentModel.saveComment(selectedComment,
                new AsyncResponder(saveCommentResult, handleError));
    }
    private function cancelEdit(event:* = null):void {
        removePopUp();
    }
    private function saveCommentResult(event:ResultEvent,
                                       token:AsyncToken = null):void {
        CursorManager.removeBusyCursor();
        selectedComment = event.result as Comment;
        var commentsChangedEvent:UIEvent =
                new UIEvent(UIEvent.COMMENTS_UPDATED);
        EventDispatcherFactory.getEventDispatcher()
                .dispatchEvent(commentsChangedEvent);
        removePopUp();
    }
    private function removePopUp():void {
        PopUpManager.removePopUp(_pop1 as UIComponent);
    }
}
}